<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件
/**
 * @date 2019/8/9 13:08
 * @description 打印调试函数
 * @author cxh
 */
function p(){
    echo "<pre>";
    $args = func_get_args();
    foreach ($args as $key=>$val){
        print_r($val);
        echo "<br>";
    }
    die;
}


/**
 * Write File
 *
 * Writes data to the file specified in the path.
 * Creates a new file if non-existent.
 *
 * @param	string	$path	File path
 * @param	string	$data	Data to write
 * @param	string	$mode	fopen() mode (default: 'wb')
 * @return	bool
 *
 * 'r'	只读方式打开，将文件指针指向文件头。
 * 'r+'	读写方式打开，将文件指针指向文件头。
 * 'w'	写入方式打开，将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
 * 'w+'	读写方式打开，将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
 * 'a'	写入方式打开，将文件指针指向文件末尾。如果文件不存在则尝试创建之。
 * 'a+'	读写方式打开，将文件指针指向文件末尾。如果文件不存在则尝试创建之。
 * 'x'	创建并以写入方式打开，将文件指针指向文件头。如果文件已存在，则 fopen() 调用失败并返回 FALSE，并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。这和给 底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。
 * 'x+'	创建并以读写方式打开，其他的行为和 'x' 一样。
 *
 * Windows 下提供了一个文本转换标记（'t'）可以透明地将 \n 转换为 \r\n。与此对应还可以使用 'b' 来强制使用二进制模式，这样就不会转换数据。要使用这些标记，要么用 'b' 或者用 't' 作为 mode 参数的最后一个字符。
 * 默认的转换模式依赖于 SAPI 和所使用的 PHP 版本，因此为了便于移植鼓励总是指定恰当的标记。如果是操作纯文本文件并在脚本中使用了 \n 作为行结束符，但还要期望这些文件可以被其它应用程序例如 Notepad 读取，则在 mode 中使用 't'。在所有其它情况下使用 'b'。
 * 在操作二进制文件时如果没有指定 'b' 标记，可能会碰到一些奇怪的问题，包括坏掉的图片文件以及关于 \r\n 字符的奇怪问题。
 * 为移植性考虑，强烈建议在用 fopen() 打开文件时总是使用 'b' 标记。
 *
 */
function write_file($data,$path = '',  $mode = 'ab')
{
    if(!$path) {
        $path = Date('Ymd').'.log';
    }
    $data = $data.PHP_EOL;

    if ( ! $fp = @fopen($path, $mode))
    {
        return FALSE;
    }

    flock($fp, LOCK_EX);

    for ($result = $written = 0, $length = strlen($data); $written < $length; $written += $result)
    {
        if (($result = fwrite($fp, substr($data, $written))) === FALSE)
        {
            break;
        }
    }

    flock($fp, LOCK_UN);
    fclose($fp);

    return is_int($result);
}



/**
 * @date
 * @description
 * @author cxh
 * @param $url
 * @param array $data  参数
 * @param array $headers  参数
 * @param int $timeout 超时时间
 * @return mixed
 */
function curl_get($url,$data = array(),$headers = array(),$timeout = 10){
    if(!empty($data)){
        $url = $url.'?'.http_build_query($data);;
    }
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLINFO_HEADER_OUT, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    if(stripos($url,"https://")!==FALSE) {
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);  // 从证书中检查SSL加密算法是否存在
    }
    curl_setopt($curl, CURLOPT_TIMEOUT, (int)$timeout); // 设置超时限制防止死循环
    $tmpInfo = curl_exec($curl);     //返回api的json对象
    if (curl_errno($curl)) {
        echo 'Errno'.curl_error($curl);//捕抓异常
    }
    //关闭URL请求
    curl_close($curl);
    return $tmpInfo;    //返回json对象
}




/**
 * @date
 * @description
 * @author cxh
 * @param $url
 * @param array $data 参数
 * @param int $timeout 超时时间
 * @return mixed
 */
function curl_post($url,$data = array(),$timeout = 4){ // 模拟提交数据函数
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
    if(stripos($url,"https://")!==FALSE){
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在
        curl_setopt($curl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
    }
    //curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
    //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
    //curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
    curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
    curl_setopt($curl, CURLOPT_TIMEOUT, (int)$timeout); // 设置超时限制防止死循环
    curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
    $tmpInfo = curl_exec($curl); // 执行操作
    if (curl_errno($curl)) {
        echo 'Errno'.curl_error($curl);//捕抓异常
    }
    curl_close($curl); // 关闭CURL会话
    return $tmpInfo; // 返回数据，json格式
}



/**
 * @date 2019/11/15 16:18
 * @description 判断是否是json格式
 * @author cxh
 * @param $str
 * @return bool
 */
function is_json($str){
    if(is_null(json_decode(htmlspecialchars_decode($str)))){
        return false;
    }else{
        return true;
    }
}




/**
 * @date 2019/7/9 14:50
 * @description 判断是否是手机号
 * @author cxh
 * @param $phone
 * @return bool
 */
function is_phone( $phone ) {
    $search = '/^0?1[3|4|5|6|7|8][0-9]\d{8}$/';
    if ( preg_match( $search, $phone ) ) {
        return ( true );
    } else {
        return ( false );
    }
}


/**
 * @date 2018/7/25 9:56
 * @description 检查用户名是否合法，6到20位，首位是字母，字母加数字组合
 * @author cxh
 * @param $user
 * @param int $length_start  用户名长度开始
 * @param int $length_end    用户名长度结束
 * @return bool
 */
function is_user_name($user,$length_start = null,$length_end = null)
{
    $length_start = $length_start?$length_start-1:3;
    $length_end = $length_end?$length_end-1:19;
    if (preg_match("/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){{$length_start},{$length_end}}$/",$user))
    {
        return true;
    }
    else
    {
        return false;
    }
}


/**
 * @date 2018/7/25 9:56
 * @description 检查密码是否合法，6到16位，字母加数字
 * @author cxh
 * @param $psd
 * @return bool
 */
function is_password($psd)
{
    if (preg_match("/^[a-zA-Z0-9]{6,16}$/",$psd))
    {
        return true;
    }
    else
    {
        return false;
    }
}




/**
 * @date 2019/7/11 16:38
 * @description 生成随机盐
 * @author cxh
 * @param int $length
 * @return string
 */
function generate_salt($length = 10) {
    $salt = '';
    if (empty($chars)) $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    while (strlen($salt) < $length) {
        $salt .= substr($chars, rand(0, strlen($chars) - 1), 1);
    }
    return $salt;
}


/**
 * @date 2019/11/14 8:55
 * @description 生成密码
 * @author cxh
 * @param $password
 * @param $salt
 * @return string
 */
function generate_password($password,$salt){
    return md5($password . sha1($salt));
}



/**
 * @date 2019/7/18 10:44
 * @description 生成验证码
 * @author cxh
 * @param int $num
 * @return string
 */
function generate_code($num = 4){
    // 去掉了 0 1 O l 等
    $str = "1234567890";
    $code = '';
    for ($i = 0; $i < $num; $i++) {
        $random_i = mt_rand(0, strlen($str) - 1);
        $code .= $str[$random_i];

    }
    return $code;
}



/**
 * 计算两个时间相差年月日
 * @param $date1
 * @param $date2
 * @return array
 */
function diff_date($date1,$date2){
    if(strtotime($date1)>strtotime($date2)){
        $tmp=$date2;
        $date2=$date1;
        $date1=$tmp;
    }
    list($Y1,$m1,$d1)=explode('-',$date1);
    list($Y2,$m2,$d2)=explode('-',$date2);
    $Y=$Y2-$Y1;
    $m=$m2-$m1;
    $d=$d2-$d1;
    if($d<0){
        $d+=(int)date('t',strtotime("-1 month $date2"));
        $m--;
    }
    if($m<0){
        $m+=12;
        $Y--;
    }
    return array('year'=>$Y,'month'=>$m,'day'=>$d);
}

